public with sharing class Cald_ClaimExtensionVF {
    private Callidus_Claim__c claim {get; set;}
    private ID oppId = null;
    public List<Opportunity> opportunityList {get; set;}
    public Integer expectedCredit {get; set;}   
    public Integer ytdAttainment {get; set;}    
    public String commissionRate {get; set;}    
    public Double commissionAmount {get; set;} 
    public String comments {get; set;}  
    public Boolean approveButFlag {get; set;}
    public Boolean rejectButFlag {get; set;}
    public Boolean adjustAndApproveButFlag {get; set;}
    public Boolean sendInquiryButFlag {get; set;}
    public Boolean lookupPlanManagerButFlag {get; set;}
    public Boolean lookupPlanButFlag {get; set;}
    public Boolean claimedUserFlag {get; set;}
    public Boolean managerFlag {get; set;}
    public Boolean readOnlyFlag {get; set;}
    public Boolean readOnlyOwnerFlag {get; set;}
    public Boolean lookUpButFlag {get; set;}
    public Boolean withdrawButFlag {get; set;}
    public Boolean fileClaimButFlag {get; set;}
    public Boolean displayAssignedToFlag {get; set;}
    public Boolean displayDraftFlag {get; set;}
    public Boolean displayReadOnlyFlag {get; set;}
    public Boolean displayManagerFlag {get; set;}
    public Boolean displayManagerReadOnlyFlag {get; set;}
    public List<Callidus_Claim_History__c> claimHistoriesList {get; set;}
    public List<ClaimHistories> claimHistoryList {get; set;}//WrapperClass
    public List<Callidus_Claim__c> claimObj {get; set;}
    public Callidus_Claim__c filingDateClaim {get; set;} 
             
    public Cald_ClaimExtensionVF(ApexPages.StandardController myController)
    {
        try
        {
            claim = (Callidus_Claim__c)myController.getRecord();
        
            String status = getClaimHistories();
            oppId = [select Opportunity__c from Callidus_Claim__c where id = : claim.id].Opportunity__c;
            Callidus_Claim__c[] c = [select OwnerId, CreatedBy.ID, Claim_Status__c, Assigned_To__c, Filing_Date__c from Callidus_Claim__c where id = :claim.id];
            displayManagerReadOnlyFlag = displayManagerFlag = displayDraftFlag = displayReadOnlyFlag = readOnlyOwnerFlag = readOnlyFlag = displayAssignedToFlag = false;
            if(c[0].CreatedBy.Id == UserInfo.getUserId())
            {
                lookupPlanButFlag = claimedUserFlag = withdrawButFlag = true;
                approveButFlag = adjustAndApproveButFlag = sendInquiryButFlag = lookupPlanManagerButFlag = rejectButFlag = managerFlag = fileClaimButFlag = readOnlyFlag = false;
                if(c[0].Claim_Status__c == 'Approved' || c[0].Claim_Status__c == 'Rejected')
                {
                    withdrawButFlag = claimedUserFlag = false;
                    displayReadOnlyFlag = readOnlyOwnerFlag = true;
                }
                if(c[0].Claim_Status__c == 'Pending Approval')
                {
                    claimedUserFlag = false;
                    displayReadOnlyFlag = displayAssignedToFlag = readOnlyOwnerFlag = true;
                }               
                if(c[0].Claim_Status__c == 'Withdrawn')
                {
                    withdrawButFlag = false;
                    displayDraftFlag = displayAssignedToFlag = claimedUserFlag = fileClaimButFlag = true;
                    readOnlyOwnerFlag = false;
                }
                    
            }
            else
            {
                lookupPlanButFlag = claimedUserFlag = withdrawButFlag = fileClaimButFlag = false;
                displayManagerFlag = adjustAndApproveButFlag = sendInquiryButFlag = lookupPlanManagerButFlag = managerFlag = true;
                if(c[0].Claim_Status__c == 'Approved' || c[0].Claim_Status__c == 'Rejected' || c[0].Claim_Status__c == 'Withdrawn')
                {
                    displayManagerFlag = managerFlag = approveButFlag = rejectButFlag = false;
                    displayManagerReadOnlyFlag = readOnlyFlag = true;
                }
                
                if(c[0].Claim_Status__c == 'Pending Approval' && c[0].Assigned_To__c == UserInfo.getUserId())
                    approveButFlag = rejectButFlag = true;
            }
                
            Schema.Sobjecttype s = Schema.getGlobalDescribe().get('Sales_Contract__c');
            if(s == null)
                lookUpButFlag = false;
            else
                lookUpButFlag = true;
                
            getClaim();
        }
        catch(Exception e)
        {
            ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.info, e.getMessage()));
        }
        
    }
    
    public PageReference deriveRate()
    {
        try
        {
            claimObj[0].Commission_Rate__c = (claimObj[0].Commission_Amount__c * 100) / claimObj[0].Credit__c;
            commissionRate = String.valueOf(claimObj[0].Commission_Rate__c);
            Decimal d = Decimal.valueOf(commissionRate);
            d = d.divide(1, 2);
            commissionRate = String.valueof(d);
            claimObj[0].Commission_Rate__c = Double.valueOf(commissionRate);
        }
        catch(Exception e)
        {
            ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.info, e.getMessage()));
        }
        return null;
    }    
    
    public List<Opportunity> getOpportunityDetails()
    {
        opportunityList = [select Name, Amount, AccountId, Opportunity.Account.Name, ExpectedRevenue, Type, Description, OwnerId, Opportunity.Owner.Name, CloseDate, LeadSource, Opportunity.Campaign.Name, MainCompetitors__c, OrderNumber__c, CurrentGenerators__c, TrackingNumber__c from Opportunity where id = :oppId];
        filingDateClaim = new Callidus_Claim__c(Filing_Date__c = opportunityList[0].CloseDate);
        return opportunityList;
    }
    
    public PageReference withdraw()
    {
    	try
    	{
	        ProcessInstance[] prInst = [Select Id from ProcessInstance where TargetObjectId=:claim.Id and Status='Pending'];
	        if(prInst.size()>0)     
	        {
	    	
	            ProcessInstanceWorkitem[] prInstWItem = [select Id,OriginalActorId from ProcessInstanceWorkitem where ProcessInstanceId = :prInst[0].Id]; 
	    
	            Approval.ProcessWorkitemRequest prWkItem = new Approval.ProcessWorkitemRequest();
	    
	            prWkItem.setWorkitemId(prInstWItem[0].Id);
	    
	            prWkItem.setComments('Withdrawn'); 
	                
	            prWkItem.setAction('Removed'); 
	
	            Approval.ProcessResult prResult = Approval.process(prWkItem);
	        }
	    	
	        claimObj[0].Claim_Status__c = 'Withdrawn';
            claimObj[0].Assigned_To__c = null;
	        update claimObj;
	        commissionRate = String.valueOf(claimObj[0].Commission_Rate__c);
	        commissionAmount = claimObj[0].Commission_Amount__c;
	        displayReadOnlyFlag = withdrawButFlag = false;
	        displayDraftFlag = fileClaimButFlag = true;
	        claimedUserFlag = true;
	        readOnlyOwnerFlag = false;
	        if(filingDateClaim != null)
	            filingDateClaim.Filing_Date__c = opportunityList[0].CloseDate; 
    	}
    	catch(Exception e)
    	{
    		if(e.getMessage().indexOf('ENTITY_IS_LOCKED') != -1 || e.getMessage().indexOf('INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY') != -1)
    			ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.info, 'Request your System Admin to enable <b>Recal Approval Requests</b>'));
    		else
    			ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.info, e.getMessage()));
    	}

        return null;
    }

    public PageReference lookupPlanDocument()
    {
        return null;
    }

    public PageReference fileClaim()
    {

        return null;
    }

    public PageReference approve()
    {
        try
        {
            List<User> managerList = [select ManagerId from User where id = :UserInfo.getUserId()];
            
            if(claimObj[0].Level1_Approver__c == claimObj[0].Assigned_To__c && claimObj[0].Level2_Approver__c != null && managerList.size() > 0 && managerList[0].managerId != null)
            {
                claimObj[0].Assigned_To__c = managerList[0].managerId;
                displayAssignedToFlag = true;
            }
            else if(claimObj[0].Level2_Approver__c == claimObj[0].Assigned_To__c && claimObj[0].Level3_Approver__c != null && managerList.size() > 0 && managerList[0].managerId != null)
            {
                claimObj[0].Assigned_To__c = managerList[0].managerId;
                displayAssignedToFlag = true;
            }
            else if(claimObj[0].Level3_Approver__c == claimObj[0].Assigned_To__c && claimObj[0].Level4_Approver__c != null && managerList.size() > 0 && managerList[0].managerId != null)
            {
                claimObj[0].Assigned_To__c = managerList[0].managerId;
                displayAssignedToFlag = true;
            }
            else if(claimObj[0].Level4_Approver__c == claimObj[0].Assigned_To__c && claimObj[0].Level5_Approver__c != null && managerList.size() > 0 && managerList[0].managerId != null)
            {
                claimObj[0].Assigned_To__c = managerList[0].managerId;
                displayAssignedToFlag = true;
            }
            else if(claimObj[0].Level5_Approver__c == claimObj[0].Assigned_To__c && claimObj[0].Level6_Approver__c != null && managerList.size() > 0 && managerList[0].managerId != null)
            {
                claimObj[0].Assigned_To__c = managerList[0].managerId;
                displayAssignedToFlag = true;
            }
            else if(claimObj[0].Level6_Approver__c == claimObj[0].Assigned_To__c && claimObj[0].Level7_Approver__c != null && managerList.size() > 0 && managerList[0].managerId != null)
            {
                claimObj[0].Assigned_To__c = managerList[0].managerId;
                displayAssignedToFlag = true;
            }
            else if(claimObj[0].Final_Approver__c != null)
            {
                claimObj[0].Assigned_To__c = claimObj[0].Final_Approver__c;
                displayAssignedToFlag = true;
            }
            else
                claimObj[0].Assigned_To__c = null;
            
            update claimObj;
            
            ProcessInstance[] prInst = [Select Id from ProcessInstance where TargetObjectId=:claim.Id and Status='Pending'];
            if(prInst.size()>0)     
            {
                Callidus_Claim_Audit__c ca = new Callidus_Claim_Audit__c(Claim__c = claim.id, claim_status__c = 'Approved', Approver__c = UserInfo.getUserId(), Approved_Date__c = Date.today(), Comments__c = comments);
                insert ca;

                Callidus_Claim_History__c ch = new Callidus_Claim_History__c(Claim__c = claim.id, Comments__c = comments, Action_Date__c = Date.today(), Claim_Status__c = 'Approved', User__c = UserInfo.getUserId());
                insert ch;
                String status = getClaimHistories();
    
                ProcessInstanceWorkitem[] prInstWItem = [select Id,OriginalActorId from ProcessInstanceWorkitem where ProcessInstanceId = :prInst[0].Id]; 
    
                Approval.ProcessWorkitemRequest prWkItem = new Approval.ProcessWorkitemRequest();
    
                prWkItem.setWorkitemId(prInstWItem[0].Id);
    
                prWkItem.setComments(comments); 
                
                prWkItem.setAction('Approve'); 

                Approval.ProcessResult prResult = Approval.process(prWkItem);
                
                //Hide the Approve and reject buttons
                approveButFlag = rejectButFlag = !approveButFlag;
                displayManagerReadOnlyFlag = readOnlyFlag = true;
                displayManagerFlag = managerFlag = false;
                getClaim();
            }
        }
        catch(Exception e)
        {
            ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.info, e.getMessage()));
        }
        return null;
    }

    public PageReference reject()
    {
        try
        {
            claimObj[0].Comments__c = comments;
          //  claimObj[0].Claim_Status__c = 'Approved';
            claimObj[0].Commission_Rate__c = Double.valueOf(commissionRate);
            update claimObj;
            ProcessInstance[] prInst = [Select Id from ProcessInstance where TargetObjectId=:claim.Id and Status='Pending'];
            if(prInst.size()>0)     
            {
                Callidus_Claim_Audit__c ca = new Callidus_Claim_Audit__c(Claim__c = claim.id, claim_status__c = 'Rejected', Approver__c = UserInfo.getUserId(), Approved_Date__c = Date.today(), Comments__c = comments);
                insert ca;

                Callidus_Claim_History__c ch = new Callidus_Claim_History__c(Claim__c = claim.id, Comments__c = comments, Action_Date__c = Date.today(), Claim_Status__c = 'Rejected', User__c = UserInfo.getUserId());
                insert ch;
                String status = getClaimHistories();
    
                ProcessInstanceWorkitem[] prInstWItem = [select Id,OriginalActorId from ProcessInstanceWorkitem where ProcessInstanceId = :prInst[0].Id]; 
    
                Approval.ProcessWorkitemRequest prWkItem = new Approval.ProcessWorkitemRequest();
    
                prWkItem.setWorkitemId(prInstWItem[0].Id);
    
                prWkItem.setComments(comments); 
                
                prWkItem.setAction('Reject'); 

                Approval.ProcessResult prResult = Approval.process(prWkItem);
                
                //Hide the Approve and reject buttons
                approveButFlag = rejectButFlag = !approveButFlag;
                displayManagerReadOnlyFlag = readOnlyFlag = true;
                displayManagerFlag = managerFlag = false;
                getClaim();
            }
        }
        catch(Exception e)
        {
            ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.info, e.getMessage()));
        }
        return null;
    }
    
    public Callidus_Claim__c getClaim()
    {
        claimObj = [select id, Name, Opportunity__r.Amount, Commission_Amount__c, Claim_Status__c, Commission_Rate__c, Attainment__c, Credit__c, Comments__c, Adjusted_Credit__c, Adjusted_Commission__c, Assigned_To__c, Filing_Date__c, Level1_Approver__c, Level2_Approver__c, Level3_Approver__c, Level4_Approver__c, Level5_Approver__c, Level6_Approver__c, Final_Approver__c from Callidus_Claim__c where id = :claim.id];
        //ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.info, ''+claimObj));
        if(claimObj.size() > 0)
        {
            if(claimObj[0].Claim_Status__c == 'Approved')
            {
                approveButFlag = rejectButFlag = false;
            }
            commissionRate = String.valueOf(claimObj[0].Commission_Rate__c);
        }
        
        return claimObj[0];
    }
    
    public Callidus_Claim__c getClaimData()
    {
        return claimObj[0];
    }

    private String getClaimHistories()
    {
        claimHistoriesList = [select Comments__c, Claim_Status__c, User__c, User__r.Name, Action_Date__c from Callidus_Claim_History__c where Claim__c = :claim.id order by createddate desc];
        if(claimHistoriesList.size() > 0)
            claimHistoryList = new List<ClaimHistories>();
        else 
            claimHistoryList = null;
            
        for(Callidus_Claim_History__c ch : claimHistoriesList)
        {
            claimHistoryList.add(new ClaimHistories(ch.Comments__c, ch.Claim_Status__c, ch.User__r.Name, ch.User__c, ch.Action_Date__c));
        }
        return 'success';
        //ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.info, String.valueOf(claimHistoriesList.size())+'  -----------------  '+claimHistoriesList));
    }//end of getClaimHistories()
    
    public class ClaimHistories
    {
        public String Comments {get; set;}
        public String claimStatus {get; set;}
        public String userName {get; set;}
        public ID userId {get; set;}
        public String actionDate {get; set;}
        public ClaimHistories(String com, String status, String uName, Id uId, Date d)
        {
            Comments = com; 
            claimStatus = status;
            userName = uName;
            userId = uId;
            actionDate = d.Month()+'/'+d.Day()+'/'+d.Year();
        }
    }
    
    public List<ClaimHistories> getClaimHistorys() {
        return claimHistoryList;
    }

    static testMethod void testCald_ClaimExtensionVF()
    {
        PageReference pg = Page.Cald_Claim_Detail;
        Test.setCurrentPage(pg);
        
        Opportunity o = [select Id, Name, Amount, AccountId, Opportunity.Account.Name, ExpectedRevenue, Type, Description, OwnerId, Opportunity.Owner.Name, CloseDate, LeadSource, Opportunity.Campaign.Name, MainCompetitors__c, OrderNumber__c, CurrentGenerators__c, TrackingNumber__c from Opportunity limit 1];
		Test.startTest();
        Callidus_Plan__c plan = new Callidus_Plan__c(Name = 'Test', Start_Date__c = Date.today(), End_Date__c = (Date.today() + 100), Quota__c = 1000000, Type__c = 'byRole');
        insert plan;
		List<Callidus_Plan__c> tPlan = [select Name from Callidus_Plan__c where id = :plan.id];
		for(Callidus_Plan__c p:tPlan)
		{
			System.assertEquals('Test', p.Name);
		}
        
        Callidus_Rate__c rate = new Callidus_Rate__c(Plan__c = plan.id, Min_Attainment__c = 0, Max_attainment__c = 100, Rate__c = 1, Rate_Type__c = 'Attainment');
        insert rate;
		List<Callidus_Rate__c> tRate = [select Rate_Type__c from Callidus_Rate__c where Plan__c = :plan.id];
		for(Callidus_Rate__c p:tRate)
		{
			System.assertEquals('Attainment', p.Rate_Type__c);
		}
        rate = new Callidus_Rate__c(Plan__c = plan.id, Min_Attainment__c = 100, Max_attainment__c = 110, Rate__c = 2, Rate_Type__c = 'Attainment');
        insert rate;
		tRate = [select Rate_Type__c from Callidus_Rate__c where Plan__c = :plan.id];
		for(Callidus_Rate__c p:tRate)
		{
			System.assertEquals('Attainment', p.Rate_Type__c);
		}
        
        Callidus_Claim__c c = new Callidus_Claim__c(Opportunity__c = o.id, Claim_Status__c = 'Approved', Filing_Date__c = Date.today(), Participant__c = UserInfo.getUserId(), Plan__c = plan.id);
        insert c;
		List<Callidus_Claim__c> tClaim = [select Claim_Status__c from Callidus_Claim__c where Plan__c = :plan.id];
		for(Callidus_Claim__c p:tClaim)
		{
			System.assertEquals('Approved', p.Claim_Status__c);
		}

        ApexPages.StandardController mc = new Apexpages.Standardcontroller(c);
        Cald_ClaimExtensionVF ce = new Cald_ClaimExtensionVF(mc);
        
        system.assertEquals(ce.claimObj[0], ce.getClaimData());
        system.assertEquals(ce.claimObj[0], ce.getClaim());
        system.assertEquals(null, ce.withdraw());
        system.assertEquals(null, ce.deriveRate());
        
        system.assertEquals(ce.claimHistoryList, ce.getClaimHistorys());
        
        system.assertNotEquals('Test', ce.getOpportunityDetails().get(0).Name);
        system.assertEquals(null, ce.lookupPlanDocument());
        system.assertEquals(null, ce.fileClaim());

        Callidus_Claim_Audit__c ca = new Callidus_Claim_Audit__c(Claim__c = c.id, claim_status__c = 'Filed', Submission_Date__c = Date.today(), Comments__c = '');
        insert ca;
        Callidus_Claim_Audit__c[] cca = [select claim_status__c  from Callidus_Claim_Audit__c where id = :ca.id];
        for(Callidus_Claim_Audit__c cc:cca)
        {
        	system.assertEquals('Filed', cc.claim_status__c);
        }
        
        Callidus_Claim_History__c chs = new Callidus_Claim_History__c(Claim__c = c.id, Comments__c = '', Action_Date__c = Date.today(), Claim_Status__c = 'Filed', User__c = UserInfo.getUserId());
        insert chs;
        Callidus_Claim_History__c[] chsList = [select Claim_Status__c from Callidus_Claim_History__c where id = :chs.id];
        for(Callidus_Claim_History__c cch:chsList)
        {
        	system.assertEquals('Filed', cch.Claim_Status__c);
        }
        try
        {
            Approval.ProcessSubmitRequest request =new Approval.ProcessSubmitRequest();
            request.setObjectId(c.Id);
            Approval.ProcessResult result = Approval.process(request);
        }
        catch(Exception e){}
        try
        {       
            system.assertEquals(null, ce.approve());
        }catch(Exception e){}
        try
        {       
            system.assertEquals(null, ce.reject());
        }catch(Exception e){}
        
        ClaimHistories ch = new ClaimHistories('Test', 'Pending Approval', 'Admin', UserInfo.getUserId(), Date.today());
        ce.claimHistoryList = new List<ClaimHistories>();
        ce.claimHistoryList.add(ch);
        system.assertEquals('Admin', ce.claimHistoryList.get(0).userName);
        
        ce.getClaimHistories();
        system.assertEquals('success', ce.getClaimHistories());
        
        system.assertEquals(null, ce.fileClaim());
        system.assertEquals(null, ce.lookupPlanDocument());
        Test.stopTest();
    }
}